#ifndef GUI_HPP
#define GUI_HPP

/********************************************************************
	created:	2011/01/16
	filename: 	E:\C++\Red\src\Graphics\Gui\Gui.hpp
	author:		Red
	
	purpose:	GUI Engine
*********************************************************************/

#include "Widget.hpp"
#include "KeyListener.hpp"
#include "MouseListener.hpp"
#include "SFML/Graphics/RenderWindow.hpp"
#include "Lua/RedLua.hpp"
#include "Label.hpp"

namespace red {
	namespace ui{
		class REDAPI Gui : public Widget{
		public:
			/// Constructor
			Gui() {}

			/// Initialize the Gui from a RenderWindow
			/// @param pRenderWindow : RenderWindow used for drawing the GUI
			void Initialize(sf::RenderWindow &pRenderWindow);

			/// Display the whole GUI
			void Display();

			/// Send an Event to the GUI to be processed
			/// @param pEvent : The event to be processed by the Gui
			void SendEvent(const sf::Event &pEvent);

			/// Adds a Listener from its type to the GUI Lists
			/// @param pListener : Listener to add
			void AddListener(Listener* pListener);

			/// Remove a Listener from its type from one of the GUI Lists
			/// @param pListener : Listener to remove
			void RemoveListener(Listener* pListener);

		protected:
			/// Overload from Widget
			virtual void OnUpdate(WidgetParameter pParam);

		private:
			sf::RenderWindow*	mRenderWindow;		///< RenderWindow in which the GUI is drawn

			sf::View			mView;				///< View on which the GUI is drawn. Generally the Viewport

			Widget*				mHoveredWidget,		///< Currently Hovered widget
				  *				mLastHoveredWidget,	///< Last Hovered widget
				  *				mFocusedWidget,		///< Currently Focused widget
				  *				mLastFocusedWidget;	///< Last Focused widget

			MouseListenerList	mMouseListeners;	///< List of all mouselistener widgets
			KeyListenerList		mKeyListeners;		///< List of all keylistener widgets


			/// Send a received event to a Widget and its children
			/// @param pWidget : Widget receiving the event
			/// @param pEvent : Event sent
			void DistributeEvent(Widget* pWidget, const sf::Event &pEvent);

			/// Finds and sets the widget currently hovered by the mouse cursor
			/// @param pRoot  : Root widget from which the function must start its research
			/// @param pMouse : Mouse coordinates
			void FindHoveredWidget(Widget* pRoot, const Vector2F &pMouse);

			/// Finds and sets the widget currently focused by the mouse cursor
			void FindFocusedWidget();

			bool IsListener(Widget* pWidget);
		};



		/// Lua usable class for Gui
		class LuaGui{
		public:
			/// C++ Constructor (called by LuaDevice only)
			LuaGui(Gui* pGui) : mGui(pGui) { }

			/// Lua Constructor (called from Lua Script)
			LuaGui(lua_State* pState) { }

			/// C++/Lua Destructor
			~LuaGui() { 
				for (u32 i = 0; i < mLuaWidgets.size(); ++i) {
					if(mLuaWidgets[i])
						delete mLuaWidgets[i];
				}
				mLuaWidgets.clear();
			}

			/// Add a Widget to the GUI from Lua
			int AddWidget(lua_State* L);


			static const char className[];				///< Class Name, when called from script
			static Lunar<LuaGui>::RegType methods[];	///< Methods Array

		private:
			Gui* mGui;				///< Gui Pointer (set by the device using the constructor)

			WidgetList mLuaWidgets;	///< Store dynamically created Widget for destruction
			
			void AddGuiLabel(lua_State* L);
		};	
	}

}
#endif // GUI_HPP
